/*
 * @Author: duchengdong
 * @Date: 2021-10-12 18:20:19
 * @LastEditors: yangmiaomiao
 * @LastEditTime: 2021-11-18 18:08:37
 * @Description:
 */
export function uuid(): string {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (Math.random() * 16) | 0,
            v = c === 'x' ? r : (r & 0x3) | 0x8
        return v.toString(16)
    })
}
// 取url参数
export function getSearch(): any {
    let search = window.location.search.slice(1).split('&')
    let params = {}
    for (let i = 0; i < search.length; i++) {
        let param = search[i].split('=')
        params[param[0]] = decodeURIComponent(param[1])
    }
    return params
}
//平铺
export const flatDeepth = (arr: any, link = 'children') => {
    return arr.reduce((pre, cur) => pre.concat(cur[link] != null ? [{ ...cur }].concat(flatDeepth(cur[link])) : { ...cur }), [])
}
//html转码
export const htmlencode = (html: string) => {
    var temp: any = document.createElement('div')
    //2.然后将要转换的字符串设置为这个元素的innerText(ie支持)或者textContent(火狐，google支持)
    temp.textContent != undefined ? (temp.textContent = html) : (temp.innerText = html)
    //3.最后返回这个元素的innerHTML，即得到经过HTML编码转换的字符串了
    var output = temp.innerHTML
    temp = null
    return output
}
//html解码
export const htmldecode = (html: string) => {
    //1.首先动态创建一个容器标签元素，如DIV
    var temp: any = document.createElement('div')
    //2.然后将要转换的字符串设置为这个元素的innerHTML(ie，火狐，google都支持)
    temp.innerHTML = html
    //3.最后返回这个元素的innerText(ie支持)或者textContent(火狐，google支持)，即得到经过HTML解码的字符串了。
    var output = temp.innerText || temp.textContent
    temp = null
    return output
}
//Base64位转换为blob
export const dataURLtoBlob = (dataurl) => {
    var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    return new Blob([u8arr], { type: mime })
}

// 把base64 转换成文件对象
export const dataURLtoFile = (base64Str, fileName) => {
    var arr = base64Str.split(','),
        mime = arr[0].match(/:(.*?);/)[1], //base64解析出来的图片类型
        bstr = atob(arr[1]), //对base64串进行操作，去掉url头，并转换为byte   atob为window内置方法
        len = bstr.length,
        ab = new ArrayBuffer(len), //将ASCII码小于0的转换为大于0
        u8arr = new Uint8Array(ab) //
    while (len--) {
        u8arr[len] = bstr.charCodeAt(len)
    }
    // 创建新的 File 对象实例[utf-8内容，文件名称或者路径，[可选参数，type：文件中的内容mime类型]]
    return new File([u8arr], fileName, {
        type: mime,
    })
}

export const downloadImg = (element, imgName) => {
    var img: any = element // 获取要下载的图片
    var url = img.src // 获取图片地址
    var a = document.createElement('a') // 创建一个a节点插入的document
    var event = new MouseEvent('click') // 模拟鼠标click点击事件
    a.download = imgName // 设置a节点的download属性值
    a.href = url // 将图片的src赋值给a节点的href
    a.dispatchEvent(event) // 触发鼠标点击事件
}

export const downloadImage = (url, name) => {
    // 将链接地址字符内容转变成blob地址, 解决图片下载直接打开问题
    // url 为图片地址
   fetch(url).then(async res => await res.blob()).then((blob) => {
     // 创建隐藏的可下载链接
     const a = document.createElement('a');
     a.style.display = 'none';
     a.href = URL.createObjectURL(blob);
     // 保存下来的文件名
     a.download = name;
     document.body.appendChild(a);
     a.click();
     // 移除元素
     document.body.removeChild(a);
   })  
}

//防抖：在一定时间间隔内，多次调用一个方法，只会执行一次.
export function debounce(fn: any, t: number = 800) {
    let timeId: NodeJS.Timeout | null = null
    const delay = t
    return function (this: any, ...args: any) {
        if (timeId) clearTimeout(timeId)
        timeId = setTimeout(() => {
            timeId = null
            fn.apply(this, args)
        }, delay)
    }
}

//节流：多次调用方法，按照一定的时间间隔执行
export function throttle(fn: any, wait: number = 500) {
    let canRun = true // 通过闭包保存一个标记
    return function (this: any, ...args: any) {
        if (!canRun) return // 在函数开头判断标记是否为true，不为true则return
        canRun = false // 立即设置为false
        setTimeout(() => {
            // 将外部传入的函数的执行放在setTimeout中
            fn.apply(this, args)
            // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false，在开头被return掉
            canRun = true
        }, wait)
    }
}
